--- /dev/null
+* A stack overflow in the format function has been fixed.
+ Patch: fix-format-overflow-cve-2007-6109.diff
+ Provided-by: Nico Golde <nion@debian.org>
+ Date: Mon, 10 Dec 2007 02:54:44 +0100
+ Added-by: Rob Browning <rlb@defaultvalue.org>
+ Status: incorporated upstream
+
+ A stack-based buffer overflow in the format function has been fixed,
+ one that could lead to arbitrary code execution. The overflow could
+ happen when dealing with high precision values (CVE-2007-6109).
+
+Index: sid/src/editfns.c
+===================================================================
+--- sid.orig/src/editfns.c
++++ sid/src/editfns.c
+@@ -3543,8 +3543,10 @@
+ precision[n+1] = 10 * precision[n+1] + *format - '0';
+ }
+
+- if (format - this_format_start + 1 > longest_format)
+- longest_format = format - this_format_start + 1;
++ /* Extra +1 for 'l' that we may need to insert into the
++ format. */
++ if (format - this_format_start + 2 > longest_format)
++ longest_format = format - this_format_start + 2;
+
+ if (format == end)
+ error ("Format string ends in middle of format specifier");
+@@ -3605,7 +3607,7 @@
+ && *format != 'i' && *format != 'X' && *format != 'c')
+ error ("Invalid format operation %%%c", *format);
+
+- thissize = 30;
++ thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
+ if (*format == 'c')
+ {
+ if (! SINGLE_BYTE_CHAR_P (XINT (args[n]))
+@@ -3803,23 +3805,39 @@
+ format - this_format_start);
+ this_format[format - this_format_start] = 0;
+
+- if (INTEGERP (args[n]))
++ if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g')
++ sprintf (p, this_format, XFLOAT_DATA (args[n]));
++ else
+ {
+- if (format[-1] == 'd')
+- sprintf (p, this_format, XINT (args[n]));
+- /* Don't sign-extend for octal or hex printing. */
++ if (sizeof (EMACS_INT) > sizeof (int) && format[-1] != 'c')
++ {
++ /* Insert 'l' before format spec. */
++ this_format[format - this_format_start]
++ = this_format[format - this_format_start - 1];
++ this_format[format - this_format_start - 1] = 'l';
++ this_format[format - this_format_start + 1] = 0;
++ }
++
++ if (INTEGERP (args[n]))
++ {
++ if (format[-1] == 'c')
++ sprintf (p, this_format, (int) XINT (args[n]));
++ else if (format[-1] == 'd')
++ sprintf (p, this_format, XINT (args[n]));
++ /* Don't sign-extend for octal or hex printing. */
++ else
++ sprintf (p, this_format, XUINT (args[n]));
++ }
++ else if (format[-1] == 'c')
++ sprintf (p, this_format, (int) XFLOAT_DATA (args[n]));
++ else if (format[-1] == 'd')
++ /* Maybe we should use "%1.0f" instead so it also works
++ for values larger than MAXINT. */
++ sprintf (p, this_format, (EMACS_INT) XFLOAT_DATA (args[n]));
+ else
+- sprintf (p, this_format, XUINT (args[n]));
++ /* Don't sign-extend for octal or hex printing. */
++ sprintf (p, this_format, (EMACS_UINT) XFLOAT_DATA (args[n]));
+ }
+- else if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g')
+- sprintf (p, this_format, XFLOAT_DATA (args[n]));
+- else if (format[-1] == 'd')
+- /* Maybe we should use "%1.0f" instead so it also works
+- for values larger than MAXINT. */
+- sprintf (p, this_format, (EMACS_INT) XFLOAT_DATA (args[n]));
+- else
+- /* Don't sign-extend for octal or hex printing. */
+- sprintf (p, this_format, (EMACS_UINT) XFLOAT_DATA (args[n]));
+
+ if (p > buf
+ && multibyte